package com.bup.gn.utils.dialect;

import org.springframework.context.ApplicationContext;
import org.springframework.security.access.expression.SecurityExpressionHandler;
import org.thymeleaf.Arguments;
import org.thymeleaf.dom.Element;
import org.thymeleaf.dom.Node;
import org.thymeleaf.processor.element.AbstractMarkupSubstitutionElementProcessor;
import org.thymeleaf.spring3.context.SpringWebContext;

import java.util.List;
import java.util.Map;

public class AuthorizeElementProcessor extends AbstractMarkupSubstitutionElementProcessor {

    public AuthorizeElementProcessor() {
        super("authorize");
    }

    @Override
    public int getPrecedence() {
        return 1000;
    }

    private boolean valid(Arguments arguments, String expression) {
        try {
            getExpressionHandler(arguments).getExpressionParser().parseExpression(expression);
        } catch (Exception ex) {
            return false;
        }
        return true;
    }

    private SecurityExpressionHandler getExpressionHandler(Arguments arguments) {
        final ApplicationContext appCtx = ((SpringWebContext) arguments.getContext()).getApplicationContext();

        Map<String, SecurityExpressionHandler> expressionHandlers = appCtx.getBeansOfType(SecurityExpressionHandler.class);
        if (expressionHandlers.size() == 0) {
            throw new RuntimeException();
        }

        return (SecurityExpressionHandler) expressionHandlers.values().toArray()[0];
    }

    @Override
    protected List<Node> getMarkupSubstitutes(final Arguments arguments, final Element element) {
        final String expression = element.getAttributeValue("access");
        if (!valid(arguments, expression)) {
            return null;
        }
        return element.getChildren();
    }
}
